"""
Case Type   : 故障&可靠性测试
Case Name   : 文件系统故障（inode资源耗尽，句柄耗尽）时，创建目录对象
Create At   : 2022/05/07
Owner       : li-xin12345
Description :
    1.创建目录
    2.使用cfe工具注入文件系统故障：inode资源耗尽
    3.初始用户创建目录对象
    4.清除故障
    5.注入文件系统故障：系统文件句柄耗尽15s
    6.初始用户创建目录对象
    7.15s后故障恢复，初始用户创建目录对象
    8.删除目录
Expect      :
    1.创建目录成功
    2.注入故障成功
    3.创建目录对象成功
    4.清除故障成功
    5.注入故障成功
    6.创建失败，合理报错
    7.创建成功
    8.删除目录成功
History     :
    Modified by peilinqian at 2024-1-22：优化用例，恢复故障后增加等待，保证故障完全恢复完成
"""
import os
import time
import unittest

from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node


class CreateDirectory(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.userNode = Node('PrimaryDbUser')
        self.primaryRootNode = Node('PrimaryRoot')
        self.sh_primary = CommonSH('PrimaryDbUser')
        self.constant = Constant()
        self.common = Common()
        self.dir_name_1 = 'dir_object_create_directory_0002_1'
        self.dir_name_2 = 'dir_object_create_directory_0002_2'
        self.dir_path = os.path.join('/tmp', 'dir_create_directory_0002')

    def test_create_directory(self):
        text = '-----step1:创建目录,expect:创建目录成功-----'
        self.logger.info(text)
        mkdir_cmd = f"mkdir {self.dir_path} && ls -ld {self.dir_path}"
        self.logger.info(mkdir_cmd)
        mkdir_msg = self.userNode.sh(mkdir_cmd).result()
        self.logger.info(mkdir_msg)
        check_dir_cmd = f'''if [ -d {self.dir_path} ]; 
                    then echo "exists"; 
                    else echo "not exists"; fi'''
        self.logger.info(check_dir_cmd)
        mkdir_result = self.userNode.sh(check_dir_cmd).result()
        self.logger.info(mkdir_result)
        self.assertEquals("exists", mkdir_result, '执行失败' + text)
        try:
            text = "-----step2:使用cfe工具注入注入文件系统故障：inode资源耗尽，" \
                   "expect:注入故障成功-----"
            self.logger.info(text)
            inject_cmd = f'rfile_ideplenish_workmode (filename, workmode) ' \
                         f'values ({self.dir_path}, fore)'
            session = ComThread(self.common.cfe_inject,
                                args=(self.primaryRootNode,
                                      inject_cmd))
            session.setDaemon(True)
            session.start()
            session.join(60 * 30)
            inject_res = session.get_result()
            self.logger.info(inject_res)
            self.assertIn(self.constant.success_cfe_rfile_ideplenish_msg,
                          inject_res, '执行失败' + text)
            df_msg = self.primaryRootNode.sh(
                f'df -i {self.dir_path}').result()
            self.logger.info(df_msg)
            self.assertIn("100%", df_msg, '执行失败' + text)

            text = "-----step3:初始用户创建目录对象，expect:创建成功-----"
            self.logger.info(text)
            create_cmd = f"create or replace directory {self.dir_name_1} " \
                         f"as '{self.dir_path}';" \
                         f"select * from pg_directory " \
                         f"where dirname like '{self.dir_name_1}';"
            create_msg = self.sh_primary.executDbSql(create_cmd)
            self.logger.info(create_msg)
            self.assertIn(self.constant.create_directory_success_msg,
                          create_msg.splitlines()[0], '执行失败' + text)
            self.assertIn(self.dir_name_1 and '10' and self.dir_path,
                          create_msg.splitlines()[-2], '执行失败' + text)
        finally:
            text = "-----step4:清除故障，expect:清除故障成功-----"
            self.logger.info(text)
            cfe_clean_cmd = f'rfile_ideplenish_workmode ' \
                            f'where filename={self.dir_path} and workmode=fore '
            cfe_clean_res = self.common.cfe_clean(self.primaryRootNode,
                                                  cfe_clean_cmd)
            self.logger.info(cfe_clean_res)
            time.sleep(60)
            self.assertIn(self.constant.success_cfe_rfile_clean_msg,
                          cfe_clean_res, '执行失败' + text)
            df_msg = self.primaryRootNode.sh(
                f'df -i {self.dir_path}').result()
            self.logger.info(df_msg)
            self.assertNotIn("100%", df_msg, '执行失败' + text)
        try:
            text = "-----step5:使用cfe工具注入注入文件系统故障：" \
                   "系统文件句柄耗尽，expect:注入故障成功-----"
            self.logger.info(text)
            cfe_inject_cmd = f'rfile_deplenish (timeout) values (15) '
            cfe_inject_res = self.common.cfe_inject(self.primaryRootNode,
                                                    cfe_inject_cmd)
            self.logger.info(cfe_inject_res)
            self.assertIn(self.constant.SUCCESS_CFE_FULL_FILENUM_MSG,
                          cfe_inject_res, '执行失败' + text)

            text = "-----step6:初始用户创建目录对象，expect:创建失败，合理报错-----"
            self.logger.info(text)
            create_cmd = f"create or replace directory {self.dir_name_2} " \
                         f"as '{self.dir_path}';"
            create_msg = self.sh_primary.executDbSql(create_cmd)
            self.logger.info(create_msg)
            self.assertIn(self.constant.TOO_MANYY_FILE_MSG,
                          create_msg, '执行失败' + text)
        finally:
            time.sleep(15)
            text = "-----确认故障清理干净-----"
            self.logger.info(text)
            start_time = time.time()
            while True:
                time.sleep(5)
                check_cmd = f"df -h {self.dir_path}"
                check_msg = self.primaryRootNode.sh(check_cmd).result()
                self.logger.info(check_msg)
                if self.constant.TOO_MANYY_FILE_MSG not in check_msg:
                    break
                end_time = time.time()
                if end_time - start_time > 300:
                    break
            text = "-----step7:15s后故障恢复，初始用户创建目录对象,expect:创建成功-----"
            self.logger.info(text)
            create_cmd = f"create or replace directory {self.dir_name_2} " \
                         f"as '{self.dir_path}';" \
                         f"select * from pg_directory " \
                         f"where dirname like '{self.dir_name_2}';"
            create_msg = self.sh_primary.executDbSql(create_cmd)
            self.logger.info(create_msg)
            self.assertIn(self.constant.create_directory_success_msg,
                          create_msg.splitlines()[0], '执行失败' + text)
            self.assertIn(self.dir_name_2 and '10' and self.dir_path,
                          create_msg.splitlines()[-2], '执行失败' + text)

    def tearDown(self):
        text = "-----step8:删除目录，expect:删除目录成功-----"
        self.logger.info(text)
        drop_cmd = f"drop directory {self.dir_name_1};" \
                   f"drop directory {self.dir_name_2};"
        drop_msg = self.sh_primary.executDbSql(drop_cmd)
        self.logger.info(drop_msg)
        del_cmd = f"rm -rf {self.dir_path}"
        self.logger.info(del_cmd)
        del_msg = self.primaryRootNode.sh(del_cmd).result()
        self.logger.info(del_msg)
        check_dir_cmd = f'''if [ -d {self.dir_path} ]; 
                            then echo "exists"; 
                            else echo "not exists"; fi'''
        self.logger.info(check_dir_cmd)
        del_result = self.primaryRootNode.sh(check_dir_cmd).result()
        self.logger.info(del_result)
        self.assertEquals(
            2, drop_msg.count(self.constant.drop_directory_success_msg),
            '执行失败' + text)
        self.assertEquals("not exists", del_result, '执行失败' + text)
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
